﻿
namespace EasyNet.Solr.Commons
{
    using System.IO;

    public class FastOutputStream : Stream
    {
        private BufferedStream stream;

        public FastOutputStream(Stream stream)
            : this(stream, 8192)
        {

        }

        public FastOutputStream(Stream stream, int bufferSize)
        {
            this.stream = new BufferedStream(stream, bufferSize);
        }

        public void Write(int b)
        {
            stream.WriteByte((byte)b);
        }

        public void Write(byte[] b)
        {
            stream.Write(b, 0, b.Length);
        }

        public void WriteBoolean(bool v)
        {
            Write(v ? 1 : 0);
        }

        public void WriteByte(int v)
        {
            Write((byte)v);
        }

        public void WriteShort(int v)
        {
            Write((byte)(v >> 8));
            Write((byte)v);
        }

        public void WriteChar(int v)
        {
            WriteShort(v);
        }

        public void WriteInt(int v)
        {
            WriteByte((byte)(v >> 24));
            WriteByte((byte)(v >> 16));
            WriteByte((byte)(v >> 8));
            WriteByte((byte)(v));
        }

        public void WriteLong(long v)
        {
            WriteByte((byte)(v >> 56));
            WriteByte((byte)(v >> 48));
            WriteByte((byte)(v >> 40));
            WriteByte((byte)(v >> 32));
            WriteByte((byte)(v >> 24));
            WriteByte((byte)(v >> 16));
            WriteByte((byte)(v >> 8));
            WriteByte((byte)(v));
        }

        public void WriteFloat(float v)
        {
            FloatConverter floatConverter = new FloatConverter();

            WriteInt(FloatConverter.ToInt(v, ref floatConverter));
        }

        public void WriteDouble(double v)
        {
            DoubleConverter doubleConverter = new DoubleConverter();

            WriteLong(DoubleConverter.ToLong(v, ref doubleConverter));
        }

        public void WriteBytes(string s)
        {
            foreach (char c in s)
            {
                WriteByte((byte)c);
            }
        }

        public void WriteChars(string s)
        {
            foreach (char c in s)
            {
                WriteChar(c);
            }
        }

        public override bool CanRead
        {
            get { return stream.CanRead; }
        }

        public override bool CanSeek
        {
            get { return stream.CanSeek; }
        }

        public override bool CanWrite
        {
            get { return stream.CanWrite; }
        }

        public override void Flush()
        {
            stream.Flush();
        }

        public override long Length
        {
            get { return stream.Length; }
        }

        public override long Position
        {
            get
            {
                return stream.Position;
            }
            set
            {
                stream.Position = value;
            }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return stream.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return stream.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            stream.SetLength(value);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            stream.Write(buffer, offset, count);
        }
    }
}
